<?php

namespace App\Service\Message\v1_1_4;

use App\Cache\RedisKey;
use App\Cache\UserMessageConsumeCache;
use App\Cache\InviteVideoCache;
use App\Constants\ErrorCode;
use App\Constants\InviteVideoCode;
use App\Exception\ApiException;
use App\Helpers\ConfigUtil;
use App\Helpers\Helper;
use App\Helpers\ImUtil;
use App\Helpers\RedisUtil;
use App\Model\BlackWords;
use App\Model\CloseFriend;
use App\Model\CoinLog;
use App\Model\InviteVideoLog;
use App\Model\Message;
use App\Model\PayOrder;
use App\Model\Service\ConsumeService;
use App\Model\Service\NewGirlReplyPackageService;
use App\Model\Setting\SettingAppHidden;
use App\Model\User;
use App\Model\UserBlacklist;
use App\Model\UserCoin;
use App\Model\UserMsgLog;
use App\Model\UserProfile;
use App\Model\UserProfilePersonal;
use App\Model\VideoCall;
use App\Model\VoiceCall;
use App\Service\BaseService;
use App\Service\ServiceTrait\InviteVideoCheckTrait;
use App\Service\User\v1_2_1\HostListService;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

/**
 * 聊天发送收费检测
 */
class ChatChargeService extends BaseService
{
    use InviteVideoCheckTrait;

    public function handle()
    {
        $userId = $this->getUserId();
        $chatUserId = $this->request->input('chat_user_id', 0);
        $msgType = $this->request->input('msg_type', 'text');
        $msgContent = $this->request->input('msg_content', '');
        $deviceId = $this->request->input('cid', '');

        $ret['result'] = 1;
        //官方小助手
        if (User::checkOfficial([$chatUserId, $userId])) return $ret;

        //自己的资料
        $selfProfile = UserProfile::getProfile($userId);
        $profile = UserProfile::getProfile($chatUserId);
        $validAppIds = explode(',', env('CHAT_NO_LIMIT_APPID', 6));
        if ($selfProfile->gender == $profile->gender && !in_array($this->appId, $validAppIds)) {
            log_user_result($userId, "Chat:{$chatUserId}==sameGender");
            return $this->setError(ErrorCode::NO_CHAT_SAME_GENDER, "暂不允许和对方聊天哦～");
        }

        //女性
        if ($selfProfile->gender == 0 && !in_array($this->appId, $validAppIds)) {
            $newGirlTaskValid = config('act.new_girl_task_valid', '2023-03-12');

            if ($selfProfile->created_at < $newGirlTaskValid) {
                if (UserProfilePersonal::checkVerifing($userId)) {
                    return $this->setError(ErrorCode::ID_VRFYING, "你的实名信息正在审核中，请等待人工审核通过后再操作～");
                }
                $selfIsHost = UserProfile::checkRoleHost($selfProfile->role);
                if (!$selfIsHost) {
                    return $this->setError(ErrorCode::NO_ID_VRFY, "平台提倡真实交友，请先实名认证～");
                }

                $selfIsVrfy = UserProfile::checkAvatarVrfied($userId, $selfProfile);
                if ($this->curVersion >= '1.0.0' && !$selfIsVrfy) {
                    return $this->setError(ErrorCode::REAL_AVATAR_NOT_VRFY, "平台提倡真实交友，请真人照片认证后再重试～");
                }
            } else {
                $selfIsVrfy = UserProfile::checkAvatarVrfied($userId, $selfProfile);
                if ($this->curVersion >= '1.0.0' && !$selfIsVrfy) {
                    return $this->setError(ErrorCode::REAL_AVATAR_NOT_VRFY, "平台提倡真实交友，请真人照片认证后再重试～");
                }

                NewGirlReplyPackageService::checkAutoMsg((int)$userId);

                NewGirlReplyPackageService::checkUserInfo((int)$userId);
            }
        }

        //消息中敏感词
        if ($msgType == 'text' && $msgContent) {
            $checkResult = BlackWords::checkLegal($msgContent, "{$userId}-{$chatUserId}");
            if (!$checkResult['result']) {
                log_user_result($userId, "Chat:{$chatUserId}==blackWords");
                return $this->setError(ErrorCode::INPUT_SENSITIVE, "你的输入有违规文字，请重新输入～");
            }
        }

        $closeValue = CloseFriend::getCloseValue($userId, $chatUserId);
        //非主播身份
        if (!UserProfile::checkRoleHost($profile->role)) return $ret;

        $today = date('Y-m-d H:i:s');
        $actDay = InviteVideoCode::ACT_USER_DAY;
        $actDay = date('Y-m-d H:i:s',strtotime("{$selfProfile->created_at} +{$actDay} day"));
        if ($selfProfile->gender == 1 && $today <= $actDay && UserProfile::checkRoleHost($profile->role)){
            $this->inviteVideo($selfProfile->user_id, $profile->user_id,$selfProfile,$profile,$closeValue);
        }

        //没有设置私信收入
        $chatCoin = $profile->chat_coin_setting;
        if ($chatCoin <= 0) {
            log_user_result($userId, "Chat:{$chatUserId}==noChatCoinSet");
            return $ret;
        }

        //聊天消息次数
        if (Helper::checkTempExcluded($userId, SettingAppHidden::FUNC_MSG)) {
            $maxMsgLmt = Helper::checkLocationLimited($selfProfile->locate_city)
                ? env('CHAT_FREE_MSG_NUM_LIMITED', 0)
                : env('CHAT_FREE_EXCLUDE_NUM', 0);
        } else {
            $maxMsgLmt = Helper::checkLocationLimited($selfProfile->locate_city)
                ? env('CHAT_FREE_MSG_NUM_LIMITED', 0)
                : env('CHAT_FREE_MAX_NUM', 0);
        }

        if (UserMsgLog::checkChargeBeginNum($userId, $chatUserId, $deviceId, $maxMsgLmt)) {
            log_user_result($userId, "Chat:{$chatUserId}==Lmt:{$maxMsgLmt}==stillFree");
            //新人专享免费消息
            //$this->newUserFreeMsg($userId, $chatUserId, $ret);
            return $ret;
        }

        //亲密度达到
        if ($closeValue >= intval(CloseFriend::checkFuncValue('free_msg'))) {
            log_user_result($userId, "Chat:{$chatUserId}==closeValue:{$closeValue}==closeEnough");
            return $ret;
        }

        //不管够不够只要达到扣费标准 第一次就发通知
        if ($selfProfile->gender == 1 && !(UserMessageConsumeCache::isConsumeUnilateral($userId,$chatUserId))){
            if ($this->checkTipHidden()){
                $tip = '对方设置私信免打扰，与对方聊天您需支付 <font color="#F55363">' . $chatCoin . '金币/条</font>';
                Message::sendImSystemTip($userId, $chatUserId, $tip, 2);

                UserMessageConsumeCache::addConsumeData($userId,$chatUserId);
            }
        }

        //自己账户余额
        $userCoin = UserCoin::getUserInfo($userId);

        //金币不够支付
        if ($userCoin['total_coin'] < $chatCoin) {

            #发送自定义消息
            $msgType = ImUtil::MSG_TYPE_COIN_NOT_ENOUGH;
            go(function () use($userId,$chatUserId,$msgType){
                $extInfo = [
                    'sys_tip' => '您的金币不足，做任务和充值都可以获得金币继续畅聊哦~',
                    'button'  => [
                        ['nickname' => '做任务','jump'=>''],
                        ['nickname' => '充值','jump'=>''],
                    ]
                ];
                Message::cannotSend($userId,$chatUserId,$msgType,$extInfo);
            });
            log_user_result($userId, "Chat:{$chatUserId}==coinNotEnough");
            return $this->setError(ErrorCode::COIN_NOT_ENOUGH, "私信发送失败！与Ta私聊需支付{$chatCoin}金币/条，当前余额不足，请充值后重试！");
        }

        //打印日志
        log_user_result($userId, "Chat:{$chatUserId}==RemainCoin:{$userCoin['total_coin']}==ChatCoin:{$chatCoin}==Pass");
        //私聊扣费
        ConsumeService::sendPrivateMsg($userId, $chatUserId, $chatCoin);
        //额外显示的消息
        $realIncome = $chatCoin * (1 - ConfigUtil::getConsumeRate($chatUserId));
        $ret['extra_msg'] = "收入+{$realIncome}金币";
        return $ret;
    }

    /**
     * 新人免费福利私信
     */
    function newUserFreeMsg($userId = 0, $hostId = 0, &$ret = [])
    {
        //免费专享受标识
        $ret['new_free_msg'] = 1;
        // return;
        $freeChatCoin = 0.1;
        //增加主播收入
        $realIncome = $freeChatCoin; //$freeChatCoin * (1 - ConfigUtil::getConsumeRate($freeChatCoin));
        ConsumeService::gainIncome($hostId, $realIncome, CoinLog::FROM_NEW_FREE_MSG_IN, $userId);
        $ret['extra_msg'] = "收入+{$realIncome}金币";
        $ret['new_free_msg'] = 1;
    }

    /**
     * 确认tip是否隐藏
     * @return bool
     */
    private function checkTipHidden(): bool
    {
        //默认没有数据 不可以发送
        $flag = false;
        //获取数据源
        $this->curVersion = $this->request->input('version', '1.0.0');
        $this->curChannel = $this->request->input('channel', '');

        if ($this->curChannel == ''){
            return false;
        }

        //获取符合条件的数据
        $data = SettingAppHidden::getIsCheckStatusByWhere($this->curVersion,SettingAppHidden::FUNC_SEND_MSG_TIP);

        //当前时间
        $time = date('H:i');

        if (empty($data)){
            return $flag;
        }

        $weekArr = [7,1,2,3,4,5,6];
        $week = $weekArr[date('w')];

        echo $week;

        foreach ($data as $one){
            if ($time >= $one['begin_time'] && $time <= $one['end_time'] && in_array($this->curChannel,explode(',',$one['channel'])) && in_array($week,json_decode($one['week']))){
                $flag = true;
            }

            if ($flag){
                break;
            }
        }

        return $flag;
    }

    /**
     * 邀约视频逻辑
     * @param $maleId
     * @param $femaleId
     * @param $maleProfile
     * @param $femaleProfile
     * @param $closeValue
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    private function inviteVideo($maleId,$femaleId,$maleProfile,$femaleProfile,$closeValue)
    {
        if (InviteVideoCache::pairLock($maleId,$femaleId)){
            return;
        }

        //有亲密度 直接出去
        if ($closeValue > 0) {
            return;
        }

        //如果女生今天接听超过三条了 踢出去
        if (InviteVideoLog::getFemaleInviteVideoRefuseCountToday($femaleId) >= InviteVideoCode::TODAY_MAX_ANSWER_NUM_FEMALE){
            return;
        }

        //被对方拉黑 直接出去
        $checkBlack = UserBlacklist::check($femaleId, $maleId);
        if ($checkBlack) {
            return;
        }

        if (PayOrder::getUserIsPay($maleId)){
            return;
        }

        //当日拒绝的出去
        if (InviteVideoLog::getInviteVideoRefuseCountToday($maleId) >= InviteVideoCode::TODAY_MAX_REFUSE_NUM){
            return;
        }

        //单日最大接听已经过了出去
        if (InviteVideoLog::getInviteVideoCountToday($maleId) >= InviteVideoCode::TODAY_MAX_ANSWER_NUM){
            return;
        }

        //总数最大接听已经过了出去
        if (InviteVideoLog::getInviteVideoCountTotal($maleId) >= InviteVideoCode::TOTAL_MAX_ANSWER_NUM){
            return;
        }

        //记录信息
        InviteVideoCache::addInviteList($maleId,$femaleId);

        //如果弹窗了就返回
        if (InviteVideoCache::isLock($femaleId,0)){
            return;
        }

        //对方繁忙
        $permitField = 'video_permit';
        if ($femaleProfile->{$permitField} == 0) {
            return;
        }

        //对方繁忙
        if (
            VideoCall::checkUserChatting($femaleId)
        ) {
            return;
        }

        //发送视频邀约弹窗
        $this->sendInviteTip($femaleId,$maleProfile);
    }
}
